<?php

namespace App\Services;
use Hyperf\Guzzle\HandlerStackFactory;
use Hyperf\Guzzle\CoroutineHandler;
use Hyperf\Utils\ApplicationContext;
use GuzzleHttp\Client;
use AopClient;


class AlipayService
{
    public static function getUserId($code){
// 解析返回结果
        $sysParams["sign_type"] = 'RSA2';
        $sysParams["method"] = 'alipay.system.oauth.token';
        $sysParams["timestamp"] = date("Y-m-d H:i:s",time());
        $sysParams["app_id"] = config('alipay.appid');
        $sysParams["format"] = 'json';
        $apiParams['grant_type'] = 'authorization_code';
        $apiParams['code'] = $code;
        $sysParams["sign"] = self::generateSign(array_merge($apiParams, $sysParams), $sysParams["sign_type"]);
        $requestUrl = 'https://openapi.alipay.com/gateway.do'. "?";
        foreach ($sysParams as $sysParamKey => $sysParamValue) {
            if ($sysParamValue != null) {
                $requestUrl .= "$sysParamKey=" . urlencode(self::characet($sysParamValue, 'UTF-8')) . "&";
            }
        }
        $requestUrl = substr($requestUrl, 0, -1);
        $result =  self::aliPost($requestUrl, $apiParams,'form_params','UTF-8');
        return json_decode($result,true);
    }

    public static function getRedirect($sn){
//        $aop = new \AopClient();
//        $aop->gatewayUrl = config('alipay.gatewayUrl');
//        $aop->appId = config('alipay.appid');
//        $aop->signType = 'RSA2';
//        $aop->alipayrsaPublicKey = config('alipay.public_key');
//        $aop->rsaPrivateKey = config('alipay.private_key');
//        \App\Model\Normal::logger(234,'alipay-event');
//        $request = new \AlipaySystemOauthTokenRequest();
//        \App\Model\Normal::logger(345,'alipay-event');
//        $request->setGrantType('authorization_code');
//        $request->setCode($code); // 传入用户的 code
//        $request = new \AlipayOpenMiniQrcodeBindRequest();
//        $request->setBizContent();
//// 执行请求
//        $result = $aop->execute($request);
        $sysParams["sign_type"] = 'RSA2';
        $sysParams["method"] = 'alipay.open.mini.qrcode.bind';
        $sysParams["timestamp"] = date("Y-m-d H:i:s",time());
        $sysParams["app_id"] = config('alipay.appid');
        $sysParams["format"] = 'json';
        $sysParams['version'] = '1.0';
        $sysParams['charset'] ='utf-8';
        $apiParams['mode'] = "FUZZY";
        $apiParams['page_redirection'] = "pages/home/index?sn=".$sn;
        $apiParams['route_url'] = "https://ylc.yimitongxun.com/";
        $params["biz_content"] = json_encode($apiParams,JSON_UNESCAPED_UNICODE);
        $sysParams["sign"] = self::generateSign(array_merge($params, $sysParams), $sysParams["sign_type"]);
        $requestUrl = 'https://openapi.alipay.com/gateway.do'. "?";
        foreach ($sysParams as $sysParamKey => $sysParamValue) {
            if ($sysParamValue != null) {
                $requestUrl .= "$sysParamKey=" . urlencode(self::characet($sysParamValue, 'UTF-8')) . "&";
            }
        }
        $requestUrl = substr($requestUrl, 0, -1);
        $result =  self::aliPost($requestUrl, $params,'form_params','UTF-8');
        return json_decode($result,true);
    }

    protected static function sign($data, $signType = "RSA2")
    {
        $res = "-----BEGIN RSA PRIVATE KEY-----\n" .
            wordwrap(config('alipay.private_key'), 64, "\n", true) .
            "\n-----END RSA PRIVATE KEY-----";
        if ("RSA2" == $signType) {
            openssl_sign($data, $sign, $res, OPENSSL_ALGO_SHA256);
        } else {
            openssl_sign($data, $sign, $res);
        }
        $sign = base64_encode($sign);
        return $sign;
    }


    public static function getSignContent($params)
    {
        ksort($params);
        unset($params['sign']);

        $stringToBeSigned = "";
        $i = 0;
        foreach ($params as $k => $v) {
            if ("@" != substr($v, 0, 1)) {

                // 转换成目标字符集
                $v = self::characet($v, 'UTF-8');

                if ($i == 0) {
                    $stringToBeSigned .= "$k" . "=" . "$v";
                } else {
                    $stringToBeSigned .= "&" . "$k" . "=" . "$v";
                }
                $i++;
            }
        }

        unset ($k, $v);
        return $stringToBeSigned;
    }


    public static function generateSign($params, $signType = "RSA2")
    {
        $params = array_filter($params);
        $params['sign_type'] = $signType;
        return self::sign(self::getSignContent($params), $signType);
    }


    public static function characet($data, $targetCharset)
    {

        if (!empty($data)) {
            $fileType = 'UTF-8';
            if (strcasecmp($fileType, $targetCharset) != 0) {
                $data = mb_convert_encoding($data, $targetCharset, $fileType);
                //				$data = iconv($fileType, $targetCharset.'//IGNORE', $data);
            }
        }
        return $data;
    }

    /**curl
     * @param $url
     * @param $data
     * @return string
     * @throws \GuzzleHttp\Exception\GuzzleException
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    public static function curlPost($url, $data,$type = 'body')
    {
        $container = ApplicationContext::getContainer();
        $handlerStackFactory = $container->get(HandlerStackFactory::class);
        $handlerStack = $handlerStackFactory->create();
        $client = new Client(['handler' => new CoroutineHandler($handlerStack)]);

        $response = $client->post($url, [
            'headers' => [
                'Content-Type' => 'application/json',
            ],
            $type => $data
        ]);

        return $response->getBody()->getContents();
    }

    public static function aliPost($url, $data,$type = 'form_params',$charset='UTF-8')
    {
        $container = ApplicationContext::getContainer();
        $handlerStackFactory = $container->get(HandlerStackFactory::class);
        $handlerStack = $handlerStackFactory->create();
        $client = new Client(['handler' => new CoroutineHandler($handlerStack)]);
        $response = $client->post($url, [
            'headers' => [
                'Content-Type' => 'application/x-www-form-urlencoded;charset='.$charset,
            ],
            $type => $data
        ]);

        return $response->getBody()->getContents();
    }

    public static function curlGet($url,$data){
        $container = ApplicationContext::getContainer();
        $handlerStackFactory = $container->get(HandlerStackFactory::class);
        $handlerStack = $handlerStackFactory->create();
        $client = new Client(['handler' => new CoroutineHandler($handlerStack)]);
        $response = $client->get($url, [
            'headers' => [
                'Content-Type' => 'application/json',
            ],
            'query'=>$data
        ]);

        return $response->getBody()->getContents();
    }

}
